package com.zbkj.crmeb.chant.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.chant.dao.ChannelMerchantAccountDao;
import com.zbkj.crmeb.chant.model.ChannelMerchantAccount;
import com.zbkj.crmeb.chant.request.*;
import com.zbkj.crmeb.chant.response.AccountCenterResponse;
import com.zbkj.crmeb.chant.response.AccountCenterResponse.Bill;
import com.zbkj.crmeb.chant.response.SupplierAccountCenterResponse;
import com.zbkj.crmeb.chant.response.SupplierAccountCenterResponse.SupplierBill;
import com.zbkj.crmeb.chant.service.IChannelMerchantAccountService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.enums.AccountFlowTypeEnum;
import com.zbkj.crmeb.enums.CurrencyEnum;
import com.zbkj.crmeb.export.vo.SupplierFlowExcelVo;
import com.zbkj.crmeb.finance.controller.WithdrawalAuditRequest;
import com.zbkj.crmeb.finance.model.UserRecharge;
import com.zbkj.crmeb.finance.service.UserRechargeService;
import com.zbkj.crmeb.merchant.admin.service.MerStoreOrderService;
import com.zbkj.crmeb.sms.service.SmsService;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse;
import com.zbkj.crmeb.store.response.SupplierInfo;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.user.service.UserMemberRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 渠道商户
 */
@Slf4j
@Service
@Transactional
public class ChannelMerchantAccountImpl extends ServiceImpl<ChannelMerchantAccountDao, ChannelMerchantAccount> implements IChannelMerchantAccountService {
    @Autowired
    private ChannelMerchantAccountDao channelMerchantAccountDao;
    @Autowired
    private UserRechargeService userRechargeService;
    @Autowired
    private IChannelMerchantAccountService channelMerchantAccountService;
    @Autowired
    private AccountFlowService accountFlowService;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    SmsService smsService;
    @Autowired
    MerStoreOrderService merStoreOrderService;
    @Autowired
    private PurchaseGoodsService purchaseGoodsService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private UserMemberRecordService userMemberRecordService;
    @Autowired
    private SupplierService supplierService;

    @Value("${order.wxMerIds}")
    private List<Integer> wxMerIds;

    @Override
    public Integer calcMoney(ChannelMerchantAccount entity) {
        ChannelMerchantAccount channelMerchantAccount = getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount :: getMerId, entity.getMerId()));
        boolean b = false;
        boolean flag = true;
        // 金额校验
        if(null != entity.getAccount()) {
            //余额支出 且 余额小于预警金额
            if(BigDecimal.ZERO.compareTo(entity.getAccount()) > 0 && channelMerchantAccount.getAccount().compareTo(channelMerchantAccount.getWarnMoney())<0){
                smsService.sendWarningMessage(channelMerchantAccount.getMerId(),channelMerchantAccount.getWarnMoney());
            }
            if(BigDecimal.ZERO.compareTo(channelMerchantAccount.getAccount().add(entity.getAccount())) == 1) {
                b = true;
            }
            if(!(BigDecimal.ZERO.compareTo(entity.getAccount()) == 0)){
                flag = false;
            }
        }
        if(null != entity.getWithdrawAccount()) {
            if(BigDecimal.ZERO.compareTo(channelMerchantAccount.getWithdrawAccount().add(entity.getWithdrawAccount())) == 1) {
                b = true;
            }
            if(!(BigDecimal.ZERO.compareTo(entity.getWithdrawAccount()) == 0)){
                flag = false;
            }
        }
        if(null != entity.getFreezeAccount()) {
            if(BigDecimal.ZERO.compareTo(channelMerchantAccount.getFreezeAccount().add(entity.getFreezeAccount())) == 1) {
                b = true;
            }
            if(!(BigDecimal.ZERO.compareTo(entity.getFreezeAccount()) == 0)){
                flag = false;
            }
        }
        if(null != entity.getTotalMoney()) {
            if(BigDecimal.ZERO.compareTo(channelMerchantAccount.getTotalMoney().add(entity.getTotalMoney())) == 1) {
                b = true;
            }
            if(!(BigDecimal.ZERO.compareTo(entity.getTotalMoney()) == 0)){
                flag = false;
            }
        }
        if(null != entity.getCloseMoney()) {
            if(BigDecimal.ZERO.compareTo(channelMerchantAccount.getCloseMoney().add(entity.getCloseMoney())) == 1) {
                b = true;
            }
            if(!(BigDecimal.ZERO.compareTo(entity.getCloseMoney()) == 0)){
                flag = false;
            }
        }
        if(b) {
            throw new CrmebException("账户余额不足!");
        }
        if(flag){
            return 1;
        }
        return channelMerchantAccountDao.calcMoney(entity);
    }

    @Override
    public Map<String, Object> getAmountWarning(List<Integer> merIds) {
        Integer merId = merIds.get(0);
        Map<String, Object> map = new HashMap<>();
        ChannelMerchantAccount channelMerchantAccount = getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount :: getMerId, merId));
        // 金额校验
        if(null != channelMerchantAccount.getAccount()) {
            //余额支出 且 余额小于预警金额
            if(channelMerchantAccount.getAccount().compareTo(Constants.FIVE_THOUSAND_BIGDECIMAL)<0){
                map.put("isWarning", 1);
                map.put("warningData", "您的账户余额所剩不多，现有余额为"+channelMerchantAccount.getAccount()+"元，为了不影响您的后续业务，请及时充值！");
                return map;
            }

        }
        map.put("isWarning", 0);
//        map.put("isWarning", 1);
//        map.put("warningData", "您的账户余额所剩不多，现有余额为"+channelMerchantAccount.getAccount()+"元，为了不影响您的后续业务，请及时充值！");

        return map;

    }

    @Override
    public Boolean offlineRecharge(OfflineRechargeRequest request, String ip) {
        // 资金操作
        ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
        channelMerchantAccount.setMerId(request.getMerId());
        channelMerchantAccount.setAccount(request.getPrice());
        channelMerchantAccountService.calcMoney(channelMerchantAccount);
        
        // 订单记录操作
        int id = systemAdminService.getAdminId();
        String orderId = CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT);
        UserRecharge userRecharge = new UserRecharge();
        userRecharge.setMerId(request.getMerId());
        userRecharge.setUid(id);
        userRecharge.setOrderId(orderId);
        userRecharge.setPrice(request.getPrice());
        userRecharge.setType(true);
        userRecharge.setStatus(1);
        userRecharge.setRechargeType(Constants.PAY_TYPE_OFFLINE);
        userRecharge.setPaid(true);
        userRecharge.setBankName(request.getBankName());
        userRecharge.setBankNo(request.getBankNo());
        userRecharge.setCreateBank(request.getCreateBank());
        userRecharge.setIp(ip);
        userRecharge.setCredentials(CollectionUtils.isNotEmpty(request.getUrlList())? String.join(",", request.getUrlList()):null);
        userRecharge.setCreateTime(new Date());
        userRecharge.setUpdateTime(new Date());
        userRechargeService.save(userRecharge);
        
        // 流水操作
        accountFlowService.saveAccountFlow(request.getMerId(), userRecharge.getId(), id, ip, AccountFlowTypeEnum.RECHARGE, request.getPrice(), null, null, "平台给商户线下充值");
        
        return true;
    }

    @Override
    public Boolean offlineWithdrawApply(Integer merId, BigDecimal price, String ip) {
        ChannelMerchantAccount channelMerchantAccount = channelMerchantAccountService.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery()
                .eq(ChannelMerchantAccount :: getMerId, merId)
                );
        if(channelMerchantAccount == null){
            throw new CrmebException("该商户不存在!");
        }
        if(BigDecimal.ZERO.compareTo(price) == 0){
        	throw new CrmebException("请输入正确金额!");
        }
        if(StringUtils.isBlank(channelMerchantAccount.getCreateBank()) || StringUtils.isBlank(channelMerchantAccount.getBankName()) || StringUtils.isBlank(channelMerchantAccount.getBankNo())){
            throw new CrmebException("商户收款信息异常!");
        }
        if(channelMerchantAccount.getStatus()){
            throw new CrmebException("账户已冻结,不可申请提现");
        }
        // 生成提现记录
        int id = systemAdminService.getAdminId();
        String orderId = CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT);
        UserRecharge userRecharge = new UserRecharge();
        userRecharge.setMerId(merId);
        userRecharge.setUid(id);
        userRecharge.setOrderId(orderId);
        userRecharge.setPrice(price);
        userRecharge.setType(true);
        userRecharge.setStatus(0);
        userRecharge.setTradeType(2); // 提现
        userRecharge.setPaid(false);
        userRecharge.setBankName(channelMerchantAccount.getBankName());
        userRecharge.setBankNo(channelMerchantAccount.getBankNo());
        userRecharge.setCreateBank(channelMerchantAccount.getCreateBank());
        userRecharge.setIp(ip);
        userRecharge.setCreateTime(new Date());
        userRecharge.setUpdateTime(new Date());
        userRechargeService.save(userRecharge);
        
        // 可提现余额冻结
        ChannelMerchantAccount channelMerchantAccountUpdate = new ChannelMerchantAccount();
        channelMerchantAccountUpdate.setMerId(merId);
        channelMerchantAccountUpdate.setAccount(price.negate());
//        channelMerchantAccountUpdate.setWithdrawAccount(BigDecimal.ZERO.subtract(price));
        channelMerchantAccountUpdate.setFreezeAccount(price);
        channelMerchantAccountService.calcMoney(channelMerchantAccountUpdate);
        
        // 流水操作
        accountFlowService.saveAccountFlow(merId, userRecharge.getId(), id, ip, AccountFlowTypeEnum.RECHARGE, price.negate(),null, price, "商户申请提现");
        
        log.info("商户: {} 申请提现: {} ip: {}", merId, price, ip);
        
        return true;
    }

    @Override
    public Boolean offlineWithdrawAudit(UserRecharge userRecharge, WithdrawalAuditRequest req, String ip) {
        int id = systemAdminService.getAdminId();
        log.info("审核商户: {} 提现申请: {} ip: {}, status: {}, adminId: {}", userRecharge.getMerId(), userRecharge.getPrice(), ip, req.getStatus(), id);
        
        // 资金操作
        ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
        channelMerchantAccount.setMerId(userRecharge.getMerId());
        channelMerchantAccount.setFreezeAccount(BigDecimal.ZERO.subtract(userRecharge.getPrice()));
        if (-1 == req.getStatus()) {
            channelMerchantAccount.setAccount(userRecharge.getPrice());
        }
        if(1 == req.getStatus()){
            channelMerchantAccount.setCloseMoney(userRecharge.getPrice());
        }
        channelMerchantAccountService.calcMoney(channelMerchantAccount);

        // 更改订单
        userRechargeService.update(Wrappers.<UserRecharge>lambdaUpdate()
                .eq(UserRecharge :: getId, userRecharge.getId())
                .set(UserRecharge :: getStatus, req.getStatus())
                .set(UserRecharge :: getPaid, true)
                .set(UserRecharge :: getPayTime, new Date())
                .set(UserRecharge::getPaymentAmount,req.getPaymentAmount())
                .set(UserRecharge::getCredentials,CollectionUtils.isNotEmpty(req.getUrlList()) ?String.join(",", req.getUrlList()):null)
                );
        
        // 流水操作
        accountFlowService.saveAccountFlow(userRecharge.getMerId(), userRecharge.getId(), id, ip, AccountFlowTypeEnum.RECHARGE,
                channelMerchantAccount.getAccount(),null,channelMerchantAccount.getFreezeAccount(), "商户提现审核");
        
        return true;
    }

    /**
     * 补偿性充值
     * @param request
     * @param ip
     * @return
     */
    @Override
    public boolean offlineCompensatory(OfflineCompensatoryRequest request, String ip) {
        //查询该笔订单是否有补偿性退款
        StoreOrder storeOrder = storeOrderService.getOne(Wrappers.<StoreOrder>lambdaQuery().eq(StoreOrder::getOrderId, request.getOrderNo()).eq(StoreOrder::getMerId,request.getMerId()).last("LIMIT 1"));
        if(storeOrder == null){
            throw new CrmebException("该商户订单号不存在,请核对订单号!");
        }else if(storeOrder.getStatus()!=4&&storeOrder.getStatus()!=-2){
            throw new CrmebException("订单未完成,没有补偿性充值!");
        }
        //查询该订单是否已经退款
        UserRecharge recharge = userRechargeService.getOne(Wrappers.<UserRecharge>lambdaQuery().eq(UserRecharge::getOrderNum, request.getOrderNo()).eq(UserRecharge::getMerId, request.getMerId()).last("LIMIT 1"));
        if(null != recharge){
            throw new CrmebException("该笔订单已补偿性充值!");
        }
        //查询订单是否存在补偿性退款
        List<AccountFlow> accountFlowList = accountFlowService.list(Wrappers.<AccountFlow>lambdaQuery().eq(AccountFlow::getOtId, storeOrder.getId()).eq(AccountFlow::getMerId, request.getMerId()).like(AccountFlow::getRemark, "补偿性退款"));
        if(CollectionUtils.isEmpty(accountFlowList)){
            throw new CrmebException("该笔订单不存在补偿性退款!");
        }
        //补偿性退款总金额
        BigDecimal totalPrice = accountFlowList.stream().map(AccountFlow::getAccount).reduce(BigDecimal.ZERO, BigDecimal::add).negate();
        if(request.getPrice().compareTo(totalPrice)>0){
            throw new CrmebException("充值金额不能大于补偿性退款总金额!补偿性退款总金额为:"+totalPrice);
        }
        // 资金操作
        ChannelMerchantAccount channelMerchantAccount = new ChannelMerchantAccount();
        channelMerchantAccount.setMerId(request.getMerId());
        channelMerchantAccount.setAccount(request.getPrice());
        channelMerchantAccountService.calcMoney(channelMerchantAccount);
        // 订单记录操作
        int id = systemAdminService.getAdminId();
        String orderId = CrmebUtil.getOrderNo(Constants.PAY_TYPE_OFFLINE);
        UserRecharge userRecharge = new UserRecharge();
        userRecharge.setMerId(request.getMerId());
        userRecharge.setUid(id);
        userRecharge.setOrderId(orderId);
        userRecharge.setPrice(request.getPrice());
        userRecharge.setType(true);
        userRecharge.setStatus(1);
        userRecharge.setRechargeType(Constants.PAY_TYPE_OFFLINE);
        userRecharge.setPaid(true);
        userRecharge.setIp(ip);
        userRecharge.setOrderNum(request.getOrderNo());
        userRecharge.setCreateTime(new Date());
        userRecharge.setUpdateTime(new Date());
        boolean save = userRechargeService.save(userRecharge);
        // 流水操作
        accountFlowService.saveAccountFlow(request.getMerId(), userRecharge.getId(), id, ip, AccountFlowTypeEnum.RECHARGE, request.getPrice(), null, null, "补偿性充值");
        return save;
    }

    /**
     * 渠道商户账户中心
     * @param request
     * @return
     */
    @Override
    public AccountCenterResponse accountCenter(AccountCenterRequest request) {
        AccountCenterResponse accountCenterResponse = new AccountCenterResponse();
        //头部数据
        ChannelMerchantAccount merchantAccount = channelMerchantAccountService.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount::getMerId, request.getMerId()).last("LIMIT 1"));
        if(Objects.isNull(merchantAccount)){
            throw new CrmebException("该商户不存在!");
        }
        accountCenterResponse.setPayMode(1);
        if (-1 == wxMerIds.indexOf(request.getMerId())) {
            accountCenterResponse.setPayMode(0);
        }
        if(29 == request.getMerId()){
            accountCenterResponse.setPayMode(1);
        }
        BeanUtils.copyProperties(merchantAccount,accountCenterResponse);
        //列表数据
        Page<Bill> billPage = PageHelper.startPage(request.getPage(), request.getLimit());
        List<Bill> collect = getFlowList(request.getMerId(),request.getType());
        accountCenterResponse.setOrderList(CommonPage.restPage(CommonPage.copyPageInfo(billPage, collect)));
        return accountCenterResponse;
    }

    @Override
    public List<Bill> getFlowList(Integer merId, Integer type) {
        LambdaQueryWrapper<AccountFlow> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AccountFlow::getMerId,merId).orderByDesc(AccountFlow::getId);
        switch (type) {
            case 1:
                //可用余额
                lambdaQueryWrapper.isNotNull(AccountFlow::getAccount);
                break;
            case 2:
                //可提现余额
                lambdaQueryWrapper.isNotNull(AccountFlow::getWithdrawAccount);
                break;
            case 3:
                //冻结金额
                lambdaQueryWrapper.isNotNull(AccountFlow::getFreezeAccount);
                break;
            default:
                break;
        }
        List<AccountFlow> accountFlowList = accountFlowService.list(lambdaQueryWrapper);
        //返回数据处理
        return accountFlowList.stream().map(e -> {
            Bill bill = new Bill().setBillId(e.getId()).setCreateTime(e.getCreateTime())
                    .setOrderDetail(e.getRemark()).setTradeType(e.getTradeType().getCode());
            if (type == 1) {
                bill.setMoney(e.getAccount());
                bill.setResidueMoney(e.getNowAccount());
            } else if (type == 2) {
                bill.setMoney(e.getWithdrawAccount());
                bill.setResidueMoney(e.getNowWithdrawAccount());
            } else if (type == 3) {
                bill.setMoney(e.getFreezeAccount());
                bill.setResidueMoney(e.getNowFreezeAccount());
            }
            if(bill.getMoney().compareTo(BigDecimal.ZERO) == 0){
                bill.setType(bill.getOrderDetail().contains("退款") ? "支出" : "收入");
            }else {
                bill.setType(bill.getMoney().compareTo(BigDecimal.ZERO) < 0 ? "支出" : "收入");
            }
            bill.setMoney(bill.getMoney().abs());
            String orderId;
            if (AccountFlowTypeEnum.PRODUCT.equals(e.getTradeType())) {
                orderId = Optional.ofNullable(storeOrderService.getById(e.getOtId())).orElse(new StoreOrder()).getOrderId();
                //订单表
                List<StoreOrderInfo> list = storeOrderInfoService.list(Wrappers.<StoreOrderInfo>lambdaQuery().eq(StoreOrderInfo::getOrderId, e.getOtId()));
                List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
                //商品详情
                if (CollectionUtils.isNotEmpty(list)) {
                    list.forEach(order -> {
                        StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
                        BeanUtils.copyProperties(order, StoreOrderInfoVo, "info");
                        StoreOrderInfoVo.setInfo(JSON.parseObject(order.getInfo(), StoreCartResponse.class));
                        storeOrderInfoVoList.add(StoreOrderInfoVo);
                    });
                }
                bill.setProductList(storeOrderInfoVoList);
            }else {
                orderId = Optional.ofNullable(userRechargeService.getById(e.getOtId())).orElse(new UserRecharge()).getOrderId();
            }
            bill.setOrderId(orderId);
            return bill;
        }).collect(Collectors.toList());
    }

    @Override
    public SupplierAccountCenterResponse supplierAccountCenter(Integer merId, PageParamRequest pageParamRequest) {
        SupplierAccountCenterResponse response = new SupplierAccountCenterResponse();
        //头部数据
        ChannelMerchantAccount merchantAccount = channelMerchantAccountService.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount::getMerId, merId).last("LIMIT 1"));
        if (Objects.isNull(merchantAccount)) {
            throw new CrmebException("该供应商账户不存在!");
        }
        BeanUtils.copyProperties(merchantAccount, response);
        //列表数据
        Page<SupplierBill> billPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<AccountFlow> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AccountFlow::getMerId, merId).eq(AccountFlow::getTradeType, AccountFlowTypeEnum.PRODUCT.getCode()).orderByDesc(AccountFlow::getId);
        lambdaQueryWrapper.isNotNull(AccountFlow::getAccount);
        List<AccountFlow> accountFlowList = accountFlowService.list(lambdaQueryWrapper);
        //返回数据处理
        List<SupplierBill> supplierBillList = accountFlowList.stream().map(e -> {
            SupplierBill bill = new SupplierBill()
                    .setBillId(e.getId())
                    .setCreateTime(e.getCreateTime())
                    .setOrderDetail(e.getRemark())
                    .setMoney(e.getAccount());
            if (bill.getMoney().compareTo(BigDecimal.ZERO) == 0) {
                bill.setType(bill.getOrderDetail().contains("退款") ? "支出" : "收入");
            } else {
                bill.setType(bill.getMoney().compareTo(BigDecimal.ZERO) < 0 ? "支出" : "收入");
            }
            bill.setMoney(bill.getMoney().abs());
            bill.setTotalMoney(e.getNowAccount().add(e.getNowFreezeAccount()));
            PurchaseGoods purchaseGoods = purchaseGoodsService.getById(e.getOtId());
            bill.setSettlementStatus(purchaseGoods.getSettlementStatus());
            bill.setOrderId(purchaseGoods.getChannelOrderSn());
            StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(purchaseGoods.getStoreOrderInfoId());
            StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
            BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
            StoreOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class));
            bill.setMainOrderId(storeOrderInfo.getOrderId());
            bill.setProduct(StoreOrderInfoVo);
            return bill;
        }).collect(Collectors.toList());
        response.setOrderList(CommonPage.restPage(CommonPage.copyPageInfo(billPage, supplierBillList)));
        // 备用金赋值
        SupplierInfo supplierInfo = channelMerchantService.getSupplierInfo(merId);
        Supplier supplier = supplierService.getById(supplierInfo.getSupplierId());
        response.setReserveMoney(supplier.getReserveMoney());
        return response;
    }

    @Override
    public Boolean settlementSupplier(SettlementSupplierRequest request,String ip) {
        if(CollectionUtils.isEmpty(request.getBillIdList())){
            throw new CrmebException("请选择采购订单!");
        }
        List<AccountFlow> accountFlowList = accountFlowService.list(Wrappers.<AccountFlow>lambdaQuery().eq(AccountFlow::getMerId, request.getMerId()).in(AccountFlow::getId, request.getBillIdList()));
        List<Integer> pushOrderIdList = accountFlowList.stream().map(AccountFlow::getOtId).distinct().collect(Collectors.toList());
        List<PurchaseGoods> purchaseGoodsList = purchaseGoodsService.list(Wrappers.<PurchaseGoods>lambdaQuery().in(PurchaseGoods::getId, pushOrderIdList));
        if(purchaseGoodsList.stream().anyMatch(e->e.getStatus()!= 4)){
            throw new CrmebException("选择的订单中有未完成订单,请核对重新提交!");
        }
        if(purchaseGoodsList.stream().anyMatch(e->e.getSettlementStatus()== 1)){
            throw new CrmebException("选择的订单中有已结算订单,请核对重新提交!");
        }

        SupplierInfo supplierInfo = channelMerchantService.getSupplierInfo(request.getMerId());

        int adminId = systemAdminService.getAdminId();
        ChannelMerchantAccount merchant = new ChannelMerchantAccount();
        merchant.setMerId(request.getMerId());
        for (PurchaseGoods goods : purchaseGoodsList) {
            BigDecimal closePrice = goods.getGoodsPrice().subtract(goods.getRefundPrice());
            if(Objects.nonNull(supplierInfo.getCurrency()) && !supplierInfo.getCurrency().equals(CurrencyEnum.CN)){
                closePrice = closePrice.divide(goods.getExchangeRate(), 2, RoundingMode.UP);
            }
            merchant.setAccount(closePrice.negate());
            merchant.setCloseMoney(closePrice);
            channelMerchantAccountService.calcMoney(merchant);
            accountFlowService.saveAccountFlow(request.getMerId(),goods.getId(),adminId,ip,
                    AccountFlowTypeEnum.RECHARGE,closePrice.negate(),null,null, "结算订单");
            goods.setSettlementStatus(1);
        }
        purchaseGoodsService.updateBatchById(purchaseGoodsList);
        return true;
    }

    @Override
    public List<SupplierFlowExcelVo> parseSupplierExportList(List<SupplierBill> billList) {
        List<SupplierFlowExcelVo> list = new ArrayList<>();
        for (SupplierBill bill : billList) {
            SupplierFlowExcelVo vo = new SupplierFlowExcelVo();
            BeanUtils.copyProperties(bill,vo);
            vo.setCreateTime(DateFormatUtils.format(bill.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
            vo.setSettlementStatus(bill.getSettlementStatus() == 0 ? "未结算":"已结算");
            StoreOrderInfoVo product = bill.getProduct();
            if(product!=null){
                StoreProductCartProductInfoResponse productInfo = product.getInfo().getProductInfo();
                String imgUrl = productInfo.getImage();
                imgUrl = StringUtil.isEmpty(imgUrl) ? "" : imgUrl.substring(0, !imgUrl.contains("?") ? imgUrl.length() : imgUrl.indexOf("?"))+"?x-oss-process=image/resize,m_fill,w_100,h_100";
                vo.setImage(imgUrl);
                vo.setStoreName(productInfo.getStoreName());
                vo.setKeyword(productInfo.getKeyword());
                vo.setBrandName(productInfo.getBrandName());
                vo.setSuk(productInfo.getAttrInfo().getSuk());
            }
            list.add(vo);
        }
        return list;
    }

    @Override
    public AppletAccountRequest getAppletAccount(Integer merId) {
        AppletAccountRequest response = new AppletAccountRequest();
        ChannelMerchantAccount merchantAccount = this.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount::getMerId, merId).last("limit 1"));
        BeanUtils.copyProperties(merchantAccount,response);
        return response;
    }

    @Override
    public boolean saveAppletAccount(Integer merId, AppletAccountRequest request) {
        return this.update(Wrappers.<ChannelMerchantAccount>lambdaUpdate().set(ChannelMerchantAccount::getAppletBankName, request.getAppletBankName())
                .set(ChannelMerchantAccount::getAppletBankNo, request.getAppletBankNo())
                .set(ChannelMerchantAccount::getAppletCreateBank, request.getAppletCreateBank())
                .eq(ChannelMerchantAccount::getMerId, merId));
    }

    @Override
    public BigDecimal calReserveMoney(Integer supplierId, BigDecimal money) {
        Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getId, supplierId).last("limit 1"));
        if (BigDecimal.ZERO.compareTo(supplier.getReserveMoney().add(money)) == 1) {
            log.info("--------------- 储备金不足，自动结算失败，请手动结算 ---------------");
            return new BigDecimal("-1");
        }
        supplier.setReserveMoney(supplier.getReserveMoney().add(money));
        supplierService.updateById(supplier);
        return supplier.getReserveMoney();
    }

    /**
     * 账户中心查看详情
     * @param id
     * @param tag true:总后台 false:商户后台
     * @return
     */
    @Override
    public Object accountInfo(Integer id,boolean tag) {
        AccountFlow accountFlow = accountFlowService.getById(id);
        if(null == accountFlow){
            throw new CrmebException("该笔流水不存在!");
        }
        if(accountFlow.getOtId() == null){
            return null;
        }
        if(AccountFlowTypeEnum.PRODUCT.equals(accountFlow.getTradeType())){
            return  tag ? storeOrderService.info(accountFlow.getOtId()) : merStoreOrderService.info(accountFlow.getOtId());
        }else if(AccountFlowTypeEnum.RECHARGE.equals(accountFlow.getTradeType())){
            return  userRechargeService.getRechargeInfo(accountFlow.getOtId());
        }else if(AccountFlowTypeEnum.MEMBER.equals(accountFlow.getTradeType())){
            return  userMemberRecordService.getMemberInfoById(accountFlow.getOtId());
        }
        return null;
    }

    /**
     * 冻结/解冻商户账户
     * @param id
     * @return
     */
    @Override
    public Boolean accountFrozen(Integer id,Boolean status) {
        ChannelMerchantAccount merchantAccount = channelMerchantAccountService.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount::getMerId, id).last("LIMIT 1"));
        if(merchantAccount == null){
            throw new CrmebException("该商户不存在!");
        }
        if(merchantAccount.getStatus()== status){
            throw new CrmebException("参数异常!");
        }
        merchantAccount.setStatus(status);
        return channelMerchantAccountService.updateById(merchantAccount);
    }
}
